package team.seekers.hula.system.order.service;

import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lly835.bestpay.model.PayResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import team.seekers.hula.common.entity.PageResult;
import team.seekers.hula.common.entity.enums.OrderEnum;
import team.seekers.hula.common.entity.result.ApiExceptionEnum;
import team.seekers.hula.common.utils.AssertUtils;
import team.seekers.hula.course.courseUser.entity.dto.CourseUserBindDTO;
import team.seekers.hula.course.courseUser.service.CourseUserService;
import team.seekers.hula.island.islandUser.entity.dto.IslandUserBindDTO;
import team.seekers.hula.island.islandUser.service.IslandUserService;
import team.seekers.hula.system.order.dao.OrderDao;
import team.seekers.hula.system.order.entity.OrderDO;
import team.seekers.hula.system.order.entity.dto.OrderCreateReqDTO;
import team.seekers.hula.system.order.entity.dto.OrderListReqDTO;
import team.seekers.hula.system.order.entity.vo.OrderInfoVO;
import team.seekers.hula.system.order.entity.vo.OrderListVO;
import team.seekers.hula.user.user.entity.dto.UserInfoDTO;
import team.seekers.hula.user.user.entity.vo.UserBasicInfoVO;
import team.seekers.hula.user.user.service.UserService;

import java.util.ArrayList;
import java.util.Map;

/**
 * @author hbc
 */
@Service
public class OrderService {

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private UserService userService;

    @Autowired
    private IslandUserService islandUserService;

    @Autowired
    private CourseUserService courseUserService;

    @Autowired
    private PaymentService paymentService;


    public PayResponse createOrder(OrderCreateReqDTO reqDTO) {
        OrderDO orderDO = new OrderDO();
        BeanUtils.copyProperties(reqDTO,orderDO);
        orderDO.setStatus(OrderEnum.NOT_PAY.getValue());
        AssertUtils.isTrue(orderDao.save(orderDO), ApiExceptionEnum.UNKNOWN_ERROR);

        return paymentService.pay(orderDO.getId(),orderDO.getMoney(),reqDTO.getPayType(),reqDTO.getUserId());
    }




    public PageResult<OrderListVO> page(OrderListReqDTO reqDTO) {
        LambdaQueryChainWrapper<OrderDO> query = orderDao.lambdaQuery().eq(OrderDO::getUserId,reqDTO.getUserId());

        Page<OrderDO> pageResult = query.page(new Page<>(reqDTO.getPageNow(), reqDTO.getPageSize()));

        if(pageResult.getRecords().size() < 1){
            return new PageResult<>(pageResult.getTotal(), new ArrayList<>());
        }

        // TODO 填充一些商品信息

        ArrayList<String> userIds = new ArrayList<>();
        for (OrderDO orderDO : pageResult.getRecords()) {
            userIds.add(orderDO.getUserId());
        }

        Map<String, UserInfoDTO> userInfoMap = userService.userIdsToUserInfoDTOs(userIds);

        ArrayList<OrderListVO> orderListVOS = new ArrayList<>();
        for (OrderDO orderDO : pageResult.getRecords()) {
            OrderListVO listVO = new OrderListVO();
            BeanUtils.copyProperties(orderDO,listVO);
            listVO.setUserInfo(userInfoMap.get(orderDO.getUserId()));
            orderListVOS.add(listVO);
        }
        return new PageResult<>(pageResult.getTotal(), orderListVOS);
    }


    public OrderInfoVO info(String orderId) {
        OrderDO orderDO = orderDao.getById(orderId);


        OrderInfoVO infoVO = new OrderInfoVO();
        BeanUtils.copyProperties(orderDO,infoVO);

        UserBasicInfoVO userBasicInfo = userService.getBasicInfoVO(orderDO.getUserId());
        infoVO.setUserInfoVO(userBasicInfo);

//        Date now = new Date();
//        Long lastSeconds = 20*60 - (now.getTime()-orderDO.getGmtCreate().getTime())/1000;
//        if(lastSeconds < 0){
//            if(orderDO.getStatus() == 0){
//                // 设置为已过期
//                orderDO.setStatus(3);
//                orderDao.updateById(orderDO);
//            }
//            infoVO.setLastSeconds(0L);
//        }else {
//            infoVO.setLastSeconds(lastSeconds);
//        }
//
//
//        ArrayList<Long> courseIds = new ArrayList<>();
//        courseIds.add(orderDO.getCourseId());
//        HashMap<Long, CourseOrderInfoDTO> courseInfoMap = courseClient.idsToCourseOrderInfoMap(courseIds);
//        infoVO.setCourseInfo(courseInfoMap.get(orderDO.getCourseId()));

        return infoVO;
    }

    public Double getMoneyById(String orderId) {
        return orderDao.lambdaQuery().select(
                OrderDO::getId,
                OrderDO::getMoney
        ).eq(OrderDO::getId,orderId).one().getMoney();
    }

    public void removeOrder(String orderId, String userId) {
        OrderDO orderDO = orderDao.getById(orderId);
        AssertUtils.isTrue(userId.equals(orderDO.getUserId()),ApiExceptionEnum.UNKNOWN_ERROR);
        AssertUtils.isTrue(orderDao.removeById(orderId), ApiExceptionEnum.UNKNOWN_ERROR);
    }

    public void cancelOrder(String orderId,String userId) {
        OrderDO orderDO = orderDao.getById(orderId);
        AssertUtils.isTrue(userId.equals(orderDO.getUserId()),ApiExceptionEnum.UNKNOWN_ERROR);
        orderDO.setStatus(OrderEnum.CANCEL.getValue());
        AssertUtils.isTrue(orderDao.updateById(orderDO), ApiExceptionEnum.UNKNOWN_ERROR);
    }

    public void notifyPay(String orderId) {
        OrderDO orderDO = orderDao.getById(orderId);
        if(orderDO.getStatus() == 1){
            return;
        }
        orderDO.setStatus(OrderEnum.PAYED.getValue());
        AssertUtils.isTrue(orderDao.updateById(orderDO), ApiExceptionEnum.UNKNOWN_ERROR);

        //TODO:知桨或浪屿进行用户绑定
        if(orderDO.getProductType() == 0){
            // 绑定浪屿
            IslandUserBindDTO islandUserBindDTO = IslandUserBindDTO.builder()
                    .islandId(orderDO.getProductId())
                    .userId(orderDO.getUserId())
                    .role(0).build();
            islandUserService.bind(islandUserBindDTO);
        }else if(orderDO.getProductType() == 1){
            // 绑定知桨
            CourseUserBindDTO courseUserBindDTO = CourseUserBindDTO
                    .builder()
                    .userId(orderDO.getUserId())
                    .courseId(orderDO.getProductId())
                    .role(0).build();
            courseUserService.bind(courseUserBindDTO);
        }
    }
}
